xen: Replace stupid page_alloc fix.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 7 Mar 2007 11:17:03 +0000 (11:17 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 7 Mar 2007 11:17:03 +0000 (11:17 +0000)
I broke the 'correct' fix when I copied it out of an email. The
actual correct version, with an extra +1 in the for-loop header is
rather abusive of for loops, so I've changed it now to a do-while loop
and an extra comment so I don't screw up this backwards loop ever
again.

This version does actually boot. :-)

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/common/page_alloc.c

index 03c9693fa576d75940d6666b5c598b2f009806d5..2974fab254ac25dda29a93f2eeb062f9a12eecbd 100644 (file)
@@ -339,7 +339,7 @@ static void init_heap_block(heap_by_zone_and_order_t *heap_block)
 
 /* Allocate 2^@order contiguous pages. */
 static struct page_info *alloc_heap_pages(
-    unsigned int zone_lo, unsigned zone_hi,
+    unsigned int zone_lo, unsigned int zone_hi,
     unsigned int cpu, unsigned int order)
 {
     unsigned int i, j, zone;
@@ -357,25 +357,24 @@ static struct page_info *alloc_heap_pages(
 
     spin_lock(&heap_lock);
 
-    /* start with requested node, but exhaust all node memory
-     * in requested zone before failing, only calc new node
-     * value if we fail to find memory in target node, this avoids
-     * needless computation on fast-path */
+    /*
+     * Start with requested node, but exhaust all node memory in requested 
+     * zone before failing, only calc new node value if we fail to find memory 
+     * in target node, this avoids needless computation on fast-path.
+     */
     for ( i = 0; i < num_nodes; i++ )
     {
-        for ( zone = zone_hi; zone-- > zone_lo; )
-        {
-            /* check if target node can support the allocation */
-            if ( avail[node] && (avail[node][zone] >= request) )
-            {
-                /* Find smallest order which can satisfy the request. */
-                for ( j = order; j <= MAX_ORDER; j++ )
-                {
-                    if ( !list_empty(&heap(node, zone, j)) )
-                        goto found;
-                }
-            }
-        }
+        zone = zone_hi;
+        do {
+            /* Check if target node can support the allocation. */
+            if ( !avail[node] || (avail[node][zone] < request) )
+                continue;
+
+            /* Find smallest order which can satisfy the request. */
+            for ( j = order; j <= MAX_ORDER; j++ )
+                if ( !list_empty(&heap(node, zone, j)) )
+                    goto found;
+        } while ( zone-- > zone_lo ); /* careful: unsigned zone may wrap */
 
         /* Pick next node, wrapping around if needed. */
         if ( ++node == num_nodes )